﻿using System.Diagnostics;

namespace System
{
  [DebuggerStepThrough]
  public static class NumberExtensions
  {
    public static double GetFraction(this double value)
    {
      return value - ((int)value);
    }

    public static float GetFraction(this float value)
    {
      return value - ((int)value);
    }

    public static byte Val(this byte? value)
    {
      return value.GetValueOrDefault();
    }
    public static double Val(this double? value)
    {
      return value.GetValueOrDefault();
    }
    public static DateTime Val(this DateTime? value)
    {
      if (value.HasValue)
        return value.Value;
      else
        return 1.January(1900);
    }
    public static int Val(this int? value)
    {
      return value.GetValueOrDefault();
    }
    public static float Val(this float? value)
    {
      return value.GetValueOrDefault();
    }
    public static bool Val(this bool? value)
    {
      return value.GetValueOrDefault();
    }
    public static short Val(this short? value)
    {
      return value.GetValueOrDefault();
    }
    public static long Val(this long? value)
    {
      return value.GetValueOrDefault();
    }

    public static byte Val(this byte value)
    {
      return value;
    }
    public static double Val(this double value)
    {
      return value;
    }
    public static DateTime Val(this DateTime value)
    {
      return value;
    }
    public static int Val(this int value)
    {
      return value;
    }
    public static float Val(this float value)
    {
      return value;
    }
    public static bool Val(this bool value)
    {
      return value;
    }
    public static short Val(this short value)
    {
      return value;
    }
    public static long Val(this long value)
    {
      return value;
    }

    public static double FixNumber(this double? value)
    {
      if (!value.HasValue) return 0.0;
      if (double.IsNaN(value.Val()) || double.MinValue == value) return 0.0;
      return value.Val();
    }
    public static double FixNumber(this double value)
    {
      if (double.IsNaN(value) || double.MinValue == value) return 0.0;
      return value;
    }

    public static string ToString(this int? val)
    {
      return val.Val().ToString();
    }
    public static string ToString(this int? val, string format)
    {
      return val.Val().ToString(format);
    }
    public static string ToString(this float? val)
    {
      return val.Val().ToString();
    }
    public static string ToString(this float? val, string format)
    {
      return val.Val().ToString(format);
    }
    public static string ToString(this double? val)
    {
      return val.Val().ToString();
    }
    public static string ToString(this double? val, string format)
    {
      return val.Val().ToString(format);
    }
    public static string ToString(this DateTime? val)
    {
      return val.Val().ToString();
    }
    public static string ToString(this DateTime? val, string format)
    {
      return val.Val().ToString(format);
    }


    public static string ToString(this float? val, NumberFormat format)
    {
      return val.Val().ToString(format);
    }
    public static string ToString(this float val, NumberFormat format)
    {
      switch (format)
      {
        case NumberFormat._0: return val.ToString("#0");
        case NumberFormat._00: return val.ToString("#00");
        default:
        case NumberFormat._0_0: return val.ToString("#0.0");
        case NumberFormat._0_00: return val.ToString("#0.00");
      }
    }
    public static string ToString(this double? val, NumberFormat format)
    {
      return val.Val().ToString(format);
    }
    public static string ToString(this double val, NumberFormat format)
    {
      switch (format)
      {
        case NumberFormat._0: return val.ToString("#0");
        case NumberFormat._00: return val.ToString("#00");
        default:
        case NumberFormat._0_0: return val.ToString("#0.0");
        case NumberFormat._0_00: return val.ToString("#0.00");
      }
    }
  }

  public enum NumberFormat
  {
    _0_0,
    _0,
    _00,
    _0_00
  }
}